package top.mydb.hejianwei.dm.page;

import top.mydb.hejianwei.dm.pageCache.PageCache;
import top.mydb.hejianwei.utils.Parser;

/**
 * PageX是普通页面的拓展，提供了对页内数据操作的通用方法
 * 普通页面的结构：
 * [FreeSpaceOffset] short
 * [Data]
 */
public class PageX {
    private static final short OF_FREE = 0; // 空闲空间偏移量在页内的偏移

    /**
     * 初始化一个新页面
     * @param pg Page对象
     * @return 初始化的页面（本身）
     */
    public static Page initPage(Page pg) {
        // 将页头的FreeSpaceOffset设为 Page.PAGE_SIZE (指向页面末尾)
        setFSO(pg, (short) PageCache.PAGE_SIZE);
        return pg;
    }

    // 获取空闲空间偏移量
    private static short getFSO(Page pg) {
        return Parser.bytes2Short(pg.getData(), OF_FREE);
    }

    // 设置空闲空间偏移量
    private static void setFSO(Page pg, short fso) {
        byte[] raw = pg.getData();
        System.arraycopy(Parser.short2Bytes(fso), 0, raw, OF_FREE, 2);
    }

    /**
     * 向页面中插入数据
     * @param pg Page对象
     * @param data 要插入的数据
     * @return 插入数据在页面中的起始偏移量
     */
    public static short insert(Page pg, byte[] data) {
        // 标记页面为脏页
        pg.setDirty(true);
        // 获取当前空闲空间的偏移
        short offset = getFSO(pg);
        // 计算插入数据后的新偏移
        short newOffset = (short)(offset - data.length);
        // 如果空间不足，直接返回错误（-1）
        if (newOffset < 0) return -1;

        // 拷贝数据到页面
        System.arraycopy(data, 0, pg.getData(), newOffset, data.length);
        // 更新页头的空闲空间偏移
        setFSO(pg, newOffset);
        
        return newOffset;
    }

    // 创建一个新页面的初始字节数组
    public static byte[] initRaw() {
        byte[] raw = new byte[PageCache.PAGE_SIZE];
        setFSO(raw, (short) PageCache.PAGE_SIZE);
        return raw;
    }

    // 获取页面的剩余空间
    public static int getFreeSpace(Page pg) {
        return getFSO(pg);
    }

    // setFSO的重载版本，直接操作byte[]
    private static void setFSO(byte[] raw, short fso) {
        System.arraycopy(Parser.short2Bytes(fso), 0, raw, OF_FREE, 2);
    }
}